<?php
declare(strict_types=1);

namespace app\controller\admin;

use app\BaseController;
use think\facade\{Queue, Cache, Log};
use think\queue\Job;
use think\Request;

class QueueMonitorController extends BaseController
{
    /**
     * 获取队列状态
     */
    public function status()
    {
        // 获取各队列的任务数
        $queues = ['default', 'notification', 'order'];
        $stats = [];
        
        foreach ($queues as $queue) {
            $stats[$queue] = [
                'waiting' => $this->getWaitingCount($queue),
                'reserved' => $this->getReservedCount($queue),
                'failed' => $this->getFailedCount($queue)
            ];
        }
        
        // 获取最近失败的任务
        $recentFailed = $this->getRecentFailed();
        
        return $this->success('获取成功', [
            'stats' => $stats,
            'recent_failed' => $recentFailed
        ]);
    }
    
    /**
     * 获取等待中的任务数
     */
    protected function getWaitingCount($queue)
    {
        return Queue::size($queue);
    }
    
    /**
     * 获取处理中的任务数
     */
    protected function getReservedCount($queue)
    {
        return Cache::get("queue:{$queue}:reserved", 0);
    }
    
    /**
     * 获取失败的任务数
     */
    protected function getFailedCount($queue)
    {
        return Cache::get("queue:{$queue}:failed", 0);
    }
    
    /**
     * 获取最近失败的任务
     */
    protected function getRecentFailed($limit = 10)
    {
        return Cache::get('queue:recent_failed', []);
    }
    
    /**
     * 重试失败任务
     */
    public function retry(Request $request)
    {
        $id = $request->param('id');
        if (!$id) {
            return $this->error('参数错误');
        }
        
        try {
            // 获取失败任务信息
            $failed = Cache::get("queue:failed:{$id}");
            if (!$failed) {
                throw new \Exception('任务不存在');
            }
            
            // 重新推送到队列
            Queue::push($failed['class'], $failed['data'], $failed['queue']);
            
            // 删除失败记录
            Cache::delete("queue:failed:{$id}");
            
            // 更新失败计数
            $count = Cache::get("queue:{$failed['queue']}:failed", 0);
            Cache::set("queue:{$failed['queue']}:failed", max(0, $count - 1));
            
            return $this->success('重试成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 清空失败任务
     */
    public function clear(Request $request)
    {
        $queue = $request->param('queue', 'default');
        
        try {
            // 获取该队列所有失败任务ID
            $failedIds = Cache::get("queue:{$queue}:failed_ids", []);
            
            // 删除失败记录
            foreach ($failedIds as $id) {
                Cache::delete("queue:failed:{$id}");
            }
            
            // 重置计数
            Cache::set("queue:{$queue}:failed", 0);
            Cache::delete("queue:{$queue}:failed_ids");
            
            return $this->success('清理成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 获取队列配置
     */
    public function config()
    {
        $config = [
            'default' => [
                'attempts' => 3,        // 最大重试次数
                'timeout' => 60,        // 任务超时时间(秒)
                'memory' => 128,        // 内存限制(MB)
                'sleep' => 3,           // 重试等待时间(秒)
                'tries' => 3            // 最大尝试次数
            ],
            'notification' => [
                'attempts' => 3,
                'timeout' => 30,
                'memory' => 64,
                'sleep' => 1,
                'tries' => 3
            ],
            'order' => [
                'attempts' => 5,
                'timeout' => 120,
                'memory' => 256,
                'sleep' => 5,
                'tries' => 5
            ]
        ];
        
        return $this->success('获取成功', $config);
    }
    
    /**
     * 更新队列配置
     */
    public function updateConfig(Request $request)
    {
        $data = $this->validate($request->post(), [
            'queue' => 'require',
            'config' => 'require|array'
        ]);
        
        try {
            // 更新配置
            Cache::set("queue:{$data['queue']}:config", $data['config']);
            
            return $this->success('更新成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
}